<template>
    <el-container class='base_page_container'>
        <slot name='left_area' v-bind:searchForm='searchForm' />
        <el-main>
            <el-card class='box-card'>
                <header-template slot='header' ref='header'
                                 :table-ref='tableOptions.ref'
                                 :toolbar_buttons='headerOption.toolbar_buttons'
                                 :toolbar_filter='headerOption.toolbar_filter'
                                 :title="headerOption.title"
                                 :is-search="headerOption.isSearch"
                                 :is-search-input="headerOption.isSearchInput"
                                 :is-search-btn="headerOption.isSearchBtn"
                                 :is-reset="headerOption.isReset"
                                 :searchForm='searchForm'
                                 @event='handleHeaderEvent'>
                    <template slot='right_search'>
                        <slot name='right_search' v-bind:searchForm='searchForm'></slot>
                    </template>
                </header-template>
                <vxeTableTemplate ref='$table' :data='dataList' :options.sync='tableOptions'
                                  @event='handleTableEvent' />
            </el-card>
        </el-main>
        <slot />
        <!-- 监听高度变化 -->
        <resize-sensor initial @resize='handleResizeEvent' />
    </el-container>
</template>

<script>
import provide from '@common/mixins/provide'
import ResizeSensor from 'vue-resize-sensor'
import { deleteConfirmBySids } from '@common/utils/message'

export default {
    extends: provide,
    name: 'BasePage',
    components: { ResizeSensor },
    props: {
        options: {
            type: Object,
            default: null,
        },
    },
    data() {
        return {
            isCreated: false,
            searchForm: {},
            headerOption: {},
            dataList: [],
            selectionList: [],
            tableOptions: {
                ref: 'BasePageTable',
            },
        }
    },
    watch: {
        options: {
            handler() {
                if (this.isCreated) {
                    return;
                }
                this.init()
            },
            deep: true,
        },
    },
    created() {
        this.isCreated = true;
        this.init()
    },
    methods: {
        handleResizeEvent() {
            const _this = this
            this.$nextTick(() => {
                _this.$refs.$table && _this.$refs.$table.resizeTable()
            })
        },
        init() {
            const _this = this
            if (!_this.options) {
                return
            }
            if (_this.$utils.isEmpty(_this.options.url)) {
                return
            }
            if (_this.options.initSearchForm) {
                if (typeof _this.options.initSearchForm === 'function') {
                    _this.searchForm = _this.options.initSearchForm(_this.searchForm)
                } else {
                    _this.searchForm = $.extend({}, _this.searchForm, _this.options.initSearchForm || {})
                }
            }
            if (_this.options.header) {
                _this.headerOption = $.extend({}, _this.headerOption, _this.options.header || {})
            }
            if (_this.options.table) {
                _this.tableOptions = $.extend({}, _this.tableOptions, _this.options.table || {})
            }
            _this.initTableOptions()
            _this.getList(true)
        },
        initTableOptions() {
            const _this = this
            let tableOptions = $.extend({}, _this.tableOptions)
            let columns = []
            if (tableOptions.columnField) {
                let columnField = $.extend({}, tableOptions.columnField)
                delete _this.tableOptions.columnField
                for (let field in columnField) {
                    let column = {
                        label: columnField[field],
                        prop: field,
                        align: 'center',
                    }
                    if (tableOptions.columnFormatter) {
                        let formatter = tableOptions.columnFormatter[field]
                        if (typeof formatter === 'function') {
                            column.formatter = formatter
                        }
                    }
                    if (tableOptions.columnRender) {
                        let render = tableOptions.columnRender[field]
                        if (typeof render === 'function') {
                            column.render = render
                        }
                    }
                    if (tableOptions.columnCellRender) {
                        let render = tableOptions.columnCellRender[field]
                        if (render) {
                            column.cellRender = render
                        }
                    }
                    if (tableOptions.columnWidth) {
                        let width = tableOptions.columnWidth[field]
                        if (width) {
                            column.width = width
                        }
                    }
                    if (tableOptions.columnMinWidth) {
                        let minWidth = tableOptions.columnMinWidth[field]
                        if (minWidth) {
                            column.minWidth = minWidth
                        }
                    }
                    if (tableOptions.export) {
                        let exportInfo = tableOptions.export[field]
                        if (exportInfo) {
                            column = $.extend({}, column, exportInfo)
                        }
                    }
                    columns.push(column)
                }
                delete _this.tableOptions.columnFormatter
                delete _this.tableOptions.columnRender
                delete _this.tableOptions.columnCellRender
                delete _this.tableOptions.columnWidth
                delete _this.tableOptions.columnMinWidth
                delete _this.tableOptions.export
            }
            const operates = $.extend({}, tableOptions.operates)
            if (_this.$utils.isEmpty(operates.fixed)) {
                operates.fixed = 'right'
            }
            _this.tableOptions = $.extend({}, _this.tableOptions, {
                columns, operates,
            })
        },
        handleHeaderEvent(event) {
            const _this = this
            _this.searchForm = $.extend({}, _this.searchForm, event.searchForm)
            if (event.type === 'search') {
                _this.getList(true)
            } else if (event.type === 'refresh') {
                _this.getList(true)
            }
        },
        getListQueryData() {
            const _this = this
            let queryData = _this.getQueryParams(_this.tableOptions, _this.searchForm)
            if (typeof _this.options.procQuery === 'function') {
                queryData = _this.options.procQuery(queryData);
            }
            return queryData;
        },
        getList(query) {
            const _this = this
            if (query) {
                _this.tableOptions = _this.resetTablePagination(_this.tableOptions)
            }
            let queryData = _this.getListQueryData()
            _this.fetchData(_this.options.url, queryData).then(result => {
                _this.dataList = result.data || []
                _this.tableOptions = _this.setTableTotal(_this.tableOptions, result)
            }).catch(() => {
            })
        },
        handleTableEvent(event) {
            if (event.type === 'page') {
                this.getList()
                return
            }
            if (event.type === 'selectionChange') {
                this.selectionList = event.value
                this.$emit('event', event)
            }
        },
        getSelectionList() {
            return this.selectionList || [];
        },
        getTablePagination() {
            return this.tableOptions.pagination || { total: 0 }
        },
        setSearchForm(searchForm) {
            this.searchForm = $.extend({}, this.searchForm, searchForm)
        },
        openDialog(opt) {
            const _this = this
            const { type, row, title, width, component, check } = opt
            if (!component) {
                return
            }
            let dialogTitle = type === 'add' ? `创建${title}` : `编辑${title}`
            let deepRow = Object.assign({}, row)
            if (!row) {
                if (type === 'add') {
                    const sn = _this.getTablePagination().total + 1;
                    deepRow = { sn }
                }
                if (type === 'edit') {
                    if (!_this.checkSelection(_this.selectionList)) {
                        return
                    }
                    deepRow = $.extend({}, _this.selectionList[0])
                }
            }
            if (typeof check === 'function') {
                if (!check(deepRow)) {
                    return;
                }
            }
            _this.$dialog({
                title: dialogTitle,
                width: !width ? '500px' : width,
                component: {
                    value: component.value,
                    props: {
                        ...component.props,
                        row: deepRow,
                    },
                },
                confirmed() {
                    _this.getList(true)
                },
            })
        },
        deleteConfirm(row, url, check) {
            let _this = this
            deleteConfirmBySids({
                url,
                list: _this.selectionList,
                row,
                multi: true,
                check,
            }).then(() => {
                _this.getList(true)
            }).catch(() => {
            })
        },
        handleExportBase(params = {}, outputName = '导出') {
            const _this = this;
            let queryData = _this.getListQueryData()
            queryData.export = '1'
            if (this.$refs.$table) {
                this.$refs.$table.exportTable({
                    firstDataRow: 1,
                    ...params,
                    url: _this.$api.getApiUrl(_this.options.url),
                    param: queryData,
                }, outputName)
            }
        },
    },
}
</script>

<style scoped lang='less'>
.base_page_container {
    width: 100%;
    height: 100%;
    overflow: hidden;

    /deep/.search_item {
        display: flex;
        align-items: center;
        gap: 5px;

        .el-date-editor--daterange {
            width: 220px;
        }
    }
}
</style>
